package com.px.user.security;

import com.px.common.core.RespCode;
import com.px.common.core.RespException;
import com.px.common.security.TokenService;
import com.px.common.util.JsonUtil;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

import static com.px.common.security.AuthConst.TOKEN_CHECK_URL;
import static com.px.common.security.AuthConst.TOKEN_HEADER;

@Slf4j
@Service
public class TokenServiceImpl implements TokenService {

    @Autowired
    @Qualifier("restTemplate")
    RestTemplate restTemplate;

    private boolean authTokenCheck(String token){
        final HttpHeaders headers = new HttpHeaders();
        headers.set(TOKEN_HEADER, token);
        final HttpEntity<String> entity = new HttpEntity<>(headers);
        try {
            ResponseEntity<Map> res = restTemplate.exchange(TOKEN_CHECK_URL, HttpMethod.GET, entity, Map.class);
            return (Boolean) res.getBody().get("success");
        } catch (Exception e) {
            log.info("auth service error");
            return false;
        }
    }

    @Override
    public UserDetails authenticateToken(@NonNull String token) {
        if (!authTokenCheck(token))
            throw new RespException(RespCode.TOKEN_ERROR, token);

        Jwt jwt = JwtHelper.decode(token);
        Map claims = JsonUtil.fromJson(jwt.getClaims(), Map.class);
        String roles = StringUtils.isEmpty((String) claims.get("roles")) ? "" : (String) claims.get("roles");
        return User.builder()
                .username((String) claims.get("userid"))
                .password("")
                .authorities(roles.split("\\s*,\\s*"))
                .build();
    }
}
